/*
 * Copyright (C) 2020 Baidu, Inc. All Rights Reserved.
 */
package com.wty.basic.errordemo;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.junit.Test;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

/**
 * @Author wangtengyu
 * @Date 2020/7/28 1:48 下午
 * @Description 线程池的demo
 */
public class ThreadPoolDemo {


    /**
     * 测试单个单个线程捕获异常
     */
    @Test
    public void test() {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                throw new RuntimeException("错误信息在这里");
            }
        });
        thread.setUncaughtExceptionHandler((t, e) -> {
            System.out.println("测试" + t.getName() + e.getMessage());
        });
        thread.start();//单独的线程启动setUncaughtExceptionHandler是生效的，线程池失效
    }


    /**
     * 测试多线程下的异常捕获
     */
    @Test
    public void test2() {
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor
                (5, 10, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10),
                        new ThreadFactoryBuilder().setUncaughtExceptionHandler((t, ex) -> System.out.println("错误线程名" + t.getName() + "错误信息" + ex.getMessage()))
                                .setNameFormat("wtytest-threadpool-%d").build(),
                        new ThreadPoolExecutor.AbortPolicy());

        IntStream.range(1, 100).forEach(i -> threadPool.execute(() -> {
            throw new RuntimeException("错误信息在这里");
        }));
    }

    /**
     * 重写beforeExecute afterExecute  terminated
     */
    @Test
    public void test3() {
        MyThreadPoolExecutor threadPool = new MyThreadPoolExecutor
                (5, 10, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10),
                        new ThreadFactoryBuilder().setUncaughtExceptionHandler((t, ex) -> System.out.println("错误线程名" + t.getName() + "错误信息" + ex.getMessage()))
                                .setNameFormat("wtytest-threadpool-%d").build(),
                        new ThreadPoolExecutor.AbortPolicy());

        IntStream.rangeClosed(1, 1).forEach(i -> threadPool.execute(() -> {
            System.out.println(i);
        }));
        threadPool.shutdown();
    }


    /**
     * 测试单独起一个线程，进行监控
     */

    public static void main(String args[]) {
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor
                (5, 100, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10),
                        new ThreadFactoryBuilder().setUncaughtExceptionHandler((t, ex) -> System.out.println("错误线程名" + t.getName() + "错误信息" + ex.getMessage()))
                                .setNameFormat("wtytest-threadpool-%d").build(),
                        new ThreadPoolExecutor.AbortPolicy());

        IntStream.range(1, 100).forEach(i -> threadPool.execute(() -> {
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }));

        Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
            System.out.println("线程池的线程数" + threadPool.getPoolSize());
            System.out.println("线程池的活跃线程数" + threadPool.getActiveCount());
            System.out.println("线程池完成了多少任务" + threadPool.getCompletedTaskCount());
            System.out.println("线程池的队列中有多少积压任务" + threadPool.getQueue().size());
        }, 0, 1, TimeUnit.SECONDS);
    }


}
